<?php

namespace yunj\core\traits;

use yunj\core\enum\RedisKey;

trait RedisKeyGroup {

    /**
     * 定义RedisKey的枚举
     * @return RedisKey
     */
    protected abstract function redisKeyEnum();

    /**
     * 删除缓存值
     * @return int
     */
    public function delCacheValue(): int {
        try {
            $allFullKeys = [];
            $keys = static::getAllKeys($this->getValue());
            $redisKeyEnum = $this->redisKeyEnum();
            foreach ($keys as $key) {
                if (!call_user_func([$redisKeyEnum, 'isValue'], $key)) {
                    continue;
                }
                $keyObj = call_user_func([$redisKeyEnum, 'byValue'], $key);
                $keySuffixCall = $keyObj->getAttr('keySuffixCall');
                $fullKey = redis_full_key($key);
                if (is_callable($keySuffixCall)) {
                    $pattern = $fullKey . '*';
                    $fullKeys = redis_keys($pattern);
                    if ($fullKeys) {
                        $allFullKeys = array_merge($allFullKeys, $fullKeys);
                    }
                } else {
                    $allFullKeys[] = $fullKey;
                }
            }
            return $allFullKeys ? redis()->del(array_unique($allFullKeys)) : 0;
        } catch (\Throwable $e) {
            log_exception($e);
            return 0;
        }
    }

    /**
     * 获取指定分组所有的keys
     * @param string|mixed $group
     * @return array
     */
    public static function getAllKeys($group): array {
        $allkeys = [];
        static::setAllKeys($group, $allkeys);
        return $allkeys;
    }

    /**
     * 设置指定分组所有keys
     * @param string|mixed $group
     * @param array $allkeys
     */
    private static function setAllKeys($group, array &$allkeys): void {
        $allEnumAttrs = static::allEnumAttrs();
        $groupAttrs = $allEnumAttrs[$group] ?? [];
        if (!$groupAttrs) {
            return;
        }
        if ($groupKeys = $groupAttrs['keys'] ?? []) {
            $allkeys = array_merge($allkeys, $groupKeys);
        }
        foreach ($allEnumAttrs as $k => $attrs) {
            if (($parent = $attrs['parent'] ?? '') && $parent == $group) {
                static::setAllKeys($k, $allkeys);
            }
        }
    }

}
